// Copyright  2012 Petr TALLA. [petr.talla@gmail.com]
// This file is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY;  without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
// [http://www.gnu.org/copyleft/lesser.html]
//=============================================================================

package tc.crase.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;
import javax.swing.JScrollBar;

import tc.common.registry.Ref;
import tc.common.registry.RegistrySys;
import tc.common.registry.Rview;
import tc.common.utility.Dynbuff;
import tc.common.utility.DynbuffRect;
import tc.common.utility.TcCmd;

import tc.crase.cmds.CmdEx;
import tc.common.symbology.Style;
import tc.crase.sys.XdbEx;
import tc.crase.sys.XdbRoot;
import tc.crase.sys.XobjectEx;
import tc.crase.sys.Xpair;

public class ViewList extends JPanel implements Rview, MouseListener, AdjustmentListener, ComponentListener, MouseMotionListener {

	Refs refs;
	JScrollBar scroller;
	public JPanel view;
	int scrollIndex;
	
	ActiveAreaCol actives = new ActiveAreaCol();

	public ViewList(String filterType, String filterAttrName, String filterContentRegexp, boolean graph) {
		refs = new Refs(this, new FilterXobject(XdbRoot.xdbsys.current, filterType, filterAttrName, filterContentRegexp, graph));
		
		addMouseListener((MouseListener) this);

		RegistrySys.registry.views.add(this);

		view = new JPanel();
		view.setLayout(new BorderLayout());
		scroller = new JScrollBar(JScrollBar.VERTICAL, 30, 20, 0, 300);
		view.add(this, BorderLayout.CENTER);
		view.add(scroller, BorderLayout.EAST);
		addComponentListener(this);
		addMouseMotionListener(this);
		scroller.addAdjustmentListener(this);
		update();
	}

	public void adjustmentValueChanged(AdjustmentEvent e) {
		scrollIndex = e.getValue();
		repaint();
	}

	private void update() {
		int lines = getHeight() / lineHeight() - 2;
		if (lines <= 0)
			lines = 1;
		if (refs.refs.size() <= lines) {
			scroller.setVisible(false);
			scrollIndex = 0;
			return;
		}
		
		scroller.setVisible(true);

		int maxScrollIndex = refs.refs.size() - lines;
		if (scrollIndex > maxScrollIndex)
			scrollIndex = maxScrollIndex;
		scroller.setMinimum(0);
		scroller.setMaximum(maxScrollIndex);
		scroller.setValue(scrollIndex);

		repaint();
	}

	public int lineHeight() {
		return 22;
	}

	public void paint(Graphics g) {
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, getWidth(), getHeight());

		int lines = getHeight() / lineHeight();

		for (int i = scrollIndex; i < refs.refs.size(); i++) {
			int linei = i - scrollIndex;
			if (linei > lines)
				break;

			XobjectEx.ObjEx object = (XobjectEx.ObjEx) refs.refs.get(i).original;
			XobjectEx xobj = object.getObject();

			Style style = null;

			XdbEx xdbex = (XdbEx) xobj.getDb();
			style = (Style) xdbex.metadata.legend.styles.get(object.getObject().getType());

			int Y = (linei + 1) * lineHeight();
			
			int w = getWidth();

			if (xobj.getSelected()) {
				ViewRoot.styleSelected.drawIcon(g, 0, Y - lineHeight() + 6,
						                  getWidth(), lineHeight());
			}

			if (style != null) {
				style.drawIcon(g, 5, Y - 12, 14, 14);
			}

			g.setColor(Color.BLACK);

			g.drawString(Formatter.shortFormat(xobj), 26, Y);
			
			Rectangle r = new Rectangle(0, Y-lineHeight()+6, w, lineHeight());
			actives.items.add(new ActiveArea(r, ActiveArea.Type.OBJECT, xobj));
		}
		
		if (Dynbuff.view == this ) {
			Dynbuff.dynamicBufferPaint();
		}
	}

	public void removeNotify() {
		super.removeNotify();
	}

	boolean dirty = false;

	public boolean getDirty() {
		return dirty;
	}

	public void setDirty(boolean value) {
		dirty = value;
	}

	public void checkPresence() {
		refs.checkPresence();
	}
	
	public void updateRview() {
		update();
		repaint();
	}

	public void onRefChanged(Ref ref) {
		refs.onRefChanged(ref);
	}

	public void mouseClicked(MouseEvent e) {
		if (TcCmd.activeCommand instanceof CmdEx == false) return;
		CmdEx cmdex = (CmdEx)TcCmd.activeCommand;
		
		Graphics g = getGraphics();
		Dynbuff.dynamicBufferClean();
		g.dispose();
		
		if (e.getButton() == MouseEvent.BUTTON1) {
			/*int index = e.getPoint().y / lineHeight() + scrollIndex;
			if (index >= refs.refs.size())
				return;
			Ref ref = refs.refs.get(index);
			XobjectEx.ObjEx xobj = (XobjectEx.ObjEx) ref.original;
			cmdex.enterSelected(e.getPoint(), null, xobj.getObject());*/
			
			ActiveArea aa = actives.get(e.getPoint());
			
			if (aa != null) {
				if (aa.type == ActiveArea.Type.OBJECT) {
					if ( TcCmd.activeCommand instanceof CmdEx == false ) return;
					CmdEx cmd = (CmdEx)TcCmd.activeCommand;
					cmd.enterSelected(e.getPoint(), null, aa.object);
				}
			}
		} else if (e.getButton() == MouseEvent.BUTTON3) {
			cmdex.enterReset(e.getPoint(), null);
			return;
		}
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
		Graphics g = getGraphics();
		//g.setClip(clipa());
		Dynbuff.dynamicBufferClean();
	}
	
	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	};

	@Override
	public void componentHidden(ComponentEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void componentMoved(ComponentEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void componentResized(ComponentEvent e) {
		update();
		
	}

	@Override
	public void componentShown(ComponentEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		Graphics g = getGraphics();
		//g.setClip(clipa());
		Dynbuff.dynamicBufferClean();
		Point pt = e.getPoint();
		ActiveArea aa = actives.get(pt);
		if (aa == null) return;
		DynbuffRect area = new DynbuffRect(aa.rect);
		Dynbuff.dynamicBufferAdd(area, Dynbuff.Buffer.SEL, this);
		g.dispose();
	}
}
